home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Trading on the Edge
/
Trading On The Edge - CD-ROM Toolkit (Wayzata Technology)(2031)(1994).bin
/
pc
/
mac_file
/
software
/
nn_prepr
/
finrtn.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-20
|
11KB
|
336 lines
/* 05-Jul-92 (finrtn.c) Financial Routines in "C" */
#include <math.h>
/************************************************************************
* Copyright(C) 1992 High-Tech Communications. *
* 103 Buckskin Court, Sewickley, PA 15143 *
* *
* Written by Casimir C. Klimasauskas *
* *
* All rights reserved. No part of this program may be reproduced, *
* stored in a retrieval system, or tramsmitted, in any form or by any *
* means, electronic, mechanical, photocopying, recording or otherwise *
* without the prior written permission of the copyright owner, *
* High-Tech Communications. *
* *
* These programs are supplied on an "as-is" basis with no warranties *
* of fitness or operability, either express or implied. *
* *
************************************************************************
*/
#define FAST register /* for machines with lots of registers */
static char Copyright[] = {"Copyright (C) 1992, High-Tech Communications."};
/* --- MovAvgV() Computes moving average for one averaging period
*/
void MovAvgV( rvecPD, vecPD, veclI, nI )
float *rvecPD; /* (r) return vector */
float *vecPD; /* (i) pointer to start of data vector */
int veclI; /* (i) length of input (output) vector */
int nI; /* (i) number of items to average over */
{
FAST double r; /* result */
FAST float *vP; /* pointer to data */
FAST int aI; /* alternate index */
FAST int wI; /* work index */
FAST int cI; /* counter */
if ( nI <= 0 || veclI <= 0 ) return;
for( wI = 0, vP = vecPD; wI < veclI; wI++ ) {
aI = (wI < nI)? 0:(wI-nI+1);
for( r = 0., cI = 0; aI <= wI; aI++, cI++ )
r += vP[aI];
rvecPD[wI] = r / cI;
}
return;
}
/* --- RSIV() Relative Strength Index
*/
void RSIV( rvecPD, vecPD, veclI, nI )
float *rvecPD; /* (r) return vector */
float *vecPD; /* (i) pointer to start of data vector */
int veclI; /* (i) length of input (output) vector */
int nI; /* (i) number of items to compute rsi over */
{
FAST double r; /* result */
FAST float *vP; /* pointer to data */
FAST int wI; /* work index */
FAST int aI; /* alternate work index */
double lnz; /* last non-zero RSI */
double AvUpD; /* average of "ups" */
double AvDnD; /* average of "downs" */
if ( nI <= 0 || veclI <= 0 ) return;
rvecPD[0] = 0.0;
lnz = 0.;
for( wI = 1, vP = vecPD; wI < veclI; wI++ ) {
aI = (wI < nI)? 1:(wI-nI+1);
AvUpD = AvDnD = 0.;
for( ; aI <= wI; aI++ ) {
r = vP[aI] - vP[aI-1];
if ( r > 0.0 ) { AvUpD += r; }
else if ( r < 0.0 ) { AvDnD -= r; }
}
if ( AvDnD <= 0. && AvUpD <= 0. )
r = lnz; /* both zero */
else if ( AvDnD <= 0. ) r = 100.; /* all ups */
else if ( AvUpD <= 0. ) r = 0.; /* all downs */
else r = 100.-100./(1.+AvUpD/AvDnD); /* both */
if ( r < 0.001 ) r = 0.;
else lnz = r;
rvecPD[wI] = r;
}
return;
}
/* --- StochasticV() Compute the stochastic function
*/
void StochasticV( rvecPD, vecPD, veclI, nI, sI )
float *rvecPD; /* (r) return vector */
float *vecPD; /* (i) pointer to start of data vector */
int veclI; /* (i) length of input (output) vector */
int nI; /* (i) length of period to compute over */
int sI; /* (i) number of periods to "smooth" over */
{
FAST int aI; /* work index */
FAST double Mn,Mx; /* min, max */
FAST double r; /* result */
int wI; /* work index */
int cI; /* count */
/* --- compute the raw stochastic function --- */
for( wI = 0; wI < veclI; wI++ ) {
aI = (wI < nI )? 0:(wI-nI+1);
Mn = Mx = vecPD[aI++];
for(; aI <= wI; aI++ ) {
r = vecPD[aI];
if ( r < Mn ) Mn = r;
if ( r > Mx ) Mx = r;
}
if ( (Mx - Mn) < 1.e-6 ) r = 0.;
else r = (vecPD[wI] - Mn) / (Mx - Mn);
rvecPD[wI] = r;
}
if ( sI <= 1 )
return; /* no smoothing required */
/* --- smooth the function over the requested periods --- */
for( wI = veclI-1; wI >= 0; wI-- ) {
aI = (wI < sI)? 0:(wI-sI+1);
for( r = 0., cI = 0; aI <= wI; aI++, cI++ )
r += rvecPD[aI];
rvecPD[wI] = r / cI;
}
return;
}
/* --- VolatilityV() Raw volatility in price over a period of time
*/
void VolatilityV( rvecPD, vecPD, veclI, nI )
float *rvecPD; /* (r) return vector */
float *vecPD; /* (i) pointer to start of data vector */
int veclI; /* (i) length of input (output) vector */
int nI; /* (i) length of period to compute over */
{
FAST int aI; /* work index */
FAST double r; /* result */
int wI; /* work index */
for( wI = 0; wI < veclI; wI++ ) {
aI = (wI < nI)? 0:(wI-nI+1);
r = vecPD[wI] - vecPD[aI]; /* change in price */
if ( r < 0. ) r = 0.-r; /* take absolute value */
rvecPD[wI] = r;
}
return;
}
/* --- HistoricalVolatilityD() Volatility annualized over an entire data set
*/
float HistoricalVolatilityD( vecPD, veclI )
float *vecPD; /* (i) pointer to start of data vector */
int veclI; /* (i) length of input vector */
{
double r; /* return value */
double AvgLogD; /* average change */
double CumDevD; /* cumulative deviations */
double r1, r2; /* work values */
int wI; /* work index */
if ( veclI < 2 ) return( 0. );
for( AvgLogD = 0., wI = 1; wI < veclI; wI++ )
if ( (r1 = vecPD[wI]) > 0. && (r2 = vecPD[wI-1]) > 0. )
AvgLogD += log( r1 ) - log( r2 );
AvgLogD /= (veclI-1);
for( CumDevD = 0., wI = 1; wI < veclI; wI++ ) {
if ( (r1=vecPD[wI]) > 0. && (r2=vecPD[wI-1]) > 0. ) {
r = (log( r1 ) - log( r2 )) - AvgLogD;
CumDevD += (r * r);
}
}
r = sqrt( (CumDevD / (veclI-2) ) * 250. );
return( r );
}
/* --- HighLowVolatilityV() High/Low Volatility
*/
void HighLowVolatilityV( rvecPD, highPD, lowPD, veclI, nI )
float *rvecPD; /* (r) return vector */
float *highPD; /* (i) high prices */
float *lowPD; /* (i) low prices */
int veclI; /* (i) length of input (output) vector */
int nI; /* (i) length of period to compute over */
{
FAST int aI; /* work index */
FAST double r,s; /* result */
double r1,r2; /* work reals */
int wI; /* work index */
for( wI = 0; wI < veclI; wI++ ) {
if ( (wI+1) < nI ) {
rvecPD[wI] = 0.;
} else {
for( r = 0., aI = wI-nI+1; aI <= wI; aI++ ) {
if ( (r1=highPD[aI]) > 0. && (r2=lowPD[aI]) > 0. ) {
s = log( r1 ) - log( r2 );
r += (s * s);
}
}
rvecPD[wI] = sqrt( (r * 0.361)/nI );
}
}
return;
}
/* --- SlidingRegressionV() Sliding regression coefficients.
*/
void SlidingRegressionV( slopePD, interceptPD, refPD, vecPD, veclI, nI )
float *slopePD; /* (r) Slope of line */
float *interceptPD; /* (r) Intercept of line */
float *refPD; /* (i) reference (x) vector */
float *vecPD; /* (i) data vector */
int veclI; /* (i) length of data vector */
int nI; /* (i) number of days to compute slope over */
{
double Sx,Sxx, Sy,Syy, Sxy; /* sums for regression */
double num, den; /* numerator & denominator */
double rx, ry; /* work reals */
int wI; /* main work index */
int aI; /* subsidiary work index */
int lnI; /* local number of items */
int i; /* work integer */
/* NOTE: 20-Sep-92 cck: Use modified algorithm which demonstrates
* much better stability when Average of X or Y are much different
* than zero.
*/
for( wI = 0; wI < veclI; wI++ ) {
aI = (wI < nI)? 0:(wI-nI+1); /* start index */
#if 1
Sx = Sxx = Sy = Syy = Sxy = 0.;
i = aI; /* save start index */
for( lnI=0 ; aI <= wI; aI++, lnI++ ) {
rx = refPD? refPD[aI]:aI; /* "x" value */
ry = vecPD[aI]; /* "y" value */
Sx += rx; /* sum of x-values */
Sy += ry; /* sum of y-values */
}
Sx /= (double)(lnI); /* x-bar (average of x) */
Sy /= (double)(lnI); /* y-bar (average of y) */
for( aI = i; aI <= wI; aI++ ) {
rx = refPD? refPD[aI]:aI; /* "x" value */
ry = vecPD[aI]; /* "y" value */
den = (rx - Sx); /* (x-xbar) */
Sxy += den * (ry - Sy); /* (x-xbar)*(y-ybar) */
Sxx += den * den; /* (x-xbar)*(x-xbar) */
}
den = Sxy / (Sxx > (1.e-10)? Sxx:(1.e-10)); /* slope */
num = Sy - den * Sx; /* intercept */
if ( slopePD ) slopePD[wI] = den;
if ( interceptPD ) interceptPD[wI] = num;
#else
Sx = Sxx = Sy = Syy = Sxy = 0.;
for( lnI=0 ; aI <= wI; aI++, lnI++ ) {
rx = refPD? refPD[aI]:aI; /* "x" value */
ry = vecPD[aI]; /* "y" value */
Sx += rx; Sxx += rx * rx;
Sy += ry; Syy += ry * ry;
Sxy += rx * ry;
}
den = ( lnI * Sxx - Sx * Sx );
if ( fabs( den ) < 1.e-4 ) den = 0.;
else den = 1.0/den;
if ( slopePD )
slopePD[wI] = (lnI * Sxy - Sx * Sy) * den;
if ( interceptPD )
interceptPD[wI] = (Sxx * Sy - Sx * Sxy) * den;
#endif
}
return;
}
/* --- RollingCorrelationV() Rolling Correlation coefficients.
*/
void RollingCorrelationV( corrPD, refPD, vecPD, veclI, nI )
float *corrPD; /* (r) Correlation Coefficient */
float *refPD; /* (i) reference (x) vector */
float *vecPD; /* (i) data vector */
int veclI; /* (i) length of data vector */
int nI; /* (i) number of days to compute correlation over */
{
double Sx,Sxx, Sy,Syy, Sxy; /* sums for correlation */
double den; /* denominator */
double rx, ry; /* work reals */
int wI; /* main work index */
int aI; /* subsidiary work index */
int lnI; /* local number of items */
for( wI = 0; wI < veclI; wI++ ) {
aI = (wI < nI)? 0:(wI-nI+1); /* start index */
Sx = Sxx = Sy = Syy = Sxy = 0.;
for( lnI=0; aI <= wI; aI++, lnI++ ) {
rx = refPD? refPD[aI]:aI; /* "x" value */
ry = vecPD[aI]; /* "y" value */
Sx += rx;
Sy += ry;
}
Sx /= lnI; /* x-bar */
Sy /= lnI; /* y-bar */
aI = (wI < nI)? 0:(wI-nI+1); /* start index */
for( ; aI <= wI; aI++ ) {
rx = refPD? refPD[aI]:aI; /* "x" value */
ry = vecPD[aI]; /* "y" value */
Sxx += (rx - Sx) * (rx - Sx );
Syy += (ry - Sy) * (ry - Sy );
Sxy += (rx - Sx) * (ry - Sy );
}
den = sqrt( Sxx * Syy );
if ( den < 1.e-6 ) corrPD[wI] = 0.0;
else corrPD[wI] = Sxy / den;
}
return;
}